package com.aboo.infrastructure.base.util.http;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.Request.Builder;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 项目名称：
 * 类名称：  OkhttpUtil
 * 描述：  http请求基础工具类
 *
 * @author 娄安
 * 创建时间：  2020年1月14日 下午7:55:41
 * 修改人：娄安    修改日期： 2020年1月14日
 * 修改备注：
 */
@Slf4j
public class OkhttpUtil {

    /**
     * 连接超时时间
     */
    private static final long DEFAULT_CONNECT_TIME = 10000;
    /**
     * 读取超时时间
     */
    private static final long DEFAULT_READ_TIME = 30000;
    /**
     * 写入超时时间
     */
    private static final long DEFAULT_WRITE_TIME = 30000;

    /**
     * 方法名：  doPost
     * 描述：
     *
     * @param url   请求地址URL
     * @param param 请求参数键值对
     * @return 请求返回结果
     * @author 娄安
     * 创建时间：2020年1月14日 下午8:14:10
     */
    public static String doPost(String url, Map<String, String> param) {
        return doPost(url, param, null);
    }

    /**
     * 方法名：  doGet
     * 描述：
     *
     * @param url   请求地址URL
     * @param param 请求参数键值对
     * @return 请求返回结果
     * @author 娄安
     * 创建时间：2020年1月14日 下午8:14:06
     */
    public static String doGet(String url, Map<String, String> param) {
        return doGet(url, param, null);
    }

    /**
     * 方法名：  doPostJson
     * 描述：
     *
     * @param url  请求地址URL
     * @param json 请求参数的json格式内容
     * @return 请求返回结果
     * @author 娄安
     * 创建时间：2020年1月14日 下午8:14:03
     */
    public static String doPostJson(String url, Object json) {
        return doPostJson(url, json, null);
    }

    /**
     * 方法名：  doPost
     * 描述：
     *
     * @param url
     * @param param
     * @param header
     * @return
     * @author 娄安
     * 创建时间：2020年1月14日 下午8:13:47
     */
    public static String doPost(String url, Map<String, String> param, Map<String, String> header) {
        Response response = doResponse("POST", url, param, header);

        String body = "";
        try {
            if (response != null) {
                body = response.body().string();
            }
        } catch (Exception e) {
            log.error("请求失败，URL：{}", url, e);
        }

        return body;
    }

    /**
     * 方法名：  doGet
     * 描述：
     *
     * @param url
     * @param param
     * @param header
     * @return
     * @author 娄安
     * 创建时间：2020年1月14日 下午8:13:43
     */
    public static String doGet(String url, Map<String, String> param, Map<String, String> header) {
        Response response = doResponse("GET", url, param, header);

        String body = "";
        try {
            if (response != null) {
                body = response.body().string();
            }
        } catch (Exception e) {
            log.error("请求失败，URL：{}", url, e);
        }

        return body;
    }

    /**
     * 方法名：  doPostJson
     * 描述：
     *
     * @param url
     * @param json
     * @param header
     * @return
     * @author 娄安
     * 创建时间：2020年1月14日 下午8:13:38
     */
    public static String doPostJson(String url, Object json, Map<String, String> header) {
        Map<String, String> param = new HashMap<>();
        param.put("json", json != null ? JSON.toJSONString(json) : "{}");
        Response response = doResponse("POST_JSON", url, param, header);
        String body = "";

        try {
            if (response != null) {
                body = response.body().string();
            }
        } catch (Exception e) {
            log.error("请求失败，URL：{}", url, e);
        }

        return body;
    }

    /**
     * 方法名：  doResponseWithFile
     * 描述：  核心请求方法
     *
     * @param type
     * @param url
     * @param param
     * @param header
     * @return
     * @author 娄安
     * 创建时间：2020年1月14日 下午8:13:29
     */
    public static Response doResponse(String type, String url, Map<String, String> param, Map<String, String> header) {
        Response response = null;
        Request request = null;
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();

        // 设置超时时间
        clientBuilder.connectTimeout(DEFAULT_CONNECT_TIME, TimeUnit.MILLISECONDS);
        clientBuilder.readTimeout(DEFAULT_READ_TIME, TimeUnit.MILLISECONDS);
        clientBuilder.writeTimeout(DEFAULT_WRITE_TIME, TimeUnit.MILLISECONDS);

        // 添加请求头
        if (header != null) {
            clientBuilder.addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Builder headerBuilder = chain.request().newBuilder();
                    Set<Entry<String, String>> entrySet = header.entrySet();
                    Iterator<Entry<String, String>> iter = entrySet.iterator();
                    while (iter.hasNext()) {
                        Entry<String, String> entry = iter.next();
                        headerBuilder.addHeader(entry.getKey(), entry.getValue());
                    }

                    Request request = headerBuilder.build();
                    return chain.proceed(request);
                }
            });
        }

        OkHttpClient okHttpClient = clientBuilder.build();
        Request.Builder requestBuilder = new Request.Builder();
        requestBuilder.addHeader("Connection", "close");
        if ("POST".equals(type)) {
            FormBody.Builder bodyBuilder = new FormBody.Builder();
            if (param != null) {
                Set<Entry<String, String>> entrySet = param.entrySet();
                Iterator<Entry<String, String>> iter = entrySet.iterator();
                while (iter.hasNext()) {
                    Entry<String, String> entry = iter.next();
                    bodyBuilder.add(entry.getKey(), entry.getValue());
                }
            }
            RequestBody body = bodyBuilder.build();
            requestBuilder.url(url).post(body);
        } else if ("GET".equals(type)) {
            if (param != null) {
                StringBuilder sb = new StringBuilder();
                Set<Entry<String, String>> entrySet = param.entrySet();
                Iterator<Entry<String, String>> iter = entrySet.iterator();
                while (iter.hasNext()) {
                    Entry<String, String> entry = iter.next();
                    sb.append(entry.getKey()).append("=").append(entry.getValue())
                            .append("&");
                }
                url += ("?" + sb.substring(0, sb.length() - 1));
            }
            requestBuilder.url(url).get();
        } else if ("POST_JSON".equals(type)) {
            MediaType mediaType = MediaType.Companion.parse("application/json; charset=utf-8");

            String json = "{}";
            if (param != null) {
                json = param.get("json");
            }
            RequestBody body = RequestBody.Companion.create(json, mediaType);
            requestBuilder.url(url).post(body);
        }
        request = requestBuilder.build();
        Call call = okHttpClient.newCall(request);
        try {
            response = call.execute();
            if (!response.isSuccessful()) {
                log.error("请求非法，URL：{}，状态：{}", url, response.code());
            }
        } catch (IOException e) {
            log.error("请求失败，URL：{}", url, e);
            response = null;
        }

        return response;
    }

}
